﻿// Program.cs
using System;
using System.Collections.Generic;
using System.Linq;

namespace SimpleCheckInApp
{
    // 数据模型：只表示“是什么”
    class Student
    {
        public Guid Id { get; }
        public string Name { get; }

        public Student(string name)
        {
            Id = Guid.NewGuid();
            Name = name;
        }
    }

    class Course
    {
        public Guid Id { get; }
        public string Title { get; }
        // 组合：课程包含已报名学生列表
        public List<Student> EnrolledStudents { get; }

        public Course(string title)
        {
            Id = Guid.NewGuid();
            Title = title;
            EnrolledStudents = new List<Student>();
        }
    }

    class ClassSession
    {
        public Guid Id { get; }
        public Course Course { get; }
        public DateTime StartAt { get; }
        public List<AttendanceRecord> Records { get; }

        public ClassSession(Course course)
        {
            Id = Guid.NewGuid();
            Course = course;
            StartAt = DateTime.Now;
            Records = new List<AttendanceRecord>();
        }
    }

    class AttendanceRecord
    {
        public Guid StudentId { get; }
        public DateTime CheckInTime { get; }

        public AttendanceRecord(Guid studentId)
        {
            StudentId = studentId;
            CheckInTime = DateTime.Now;
        }
    }

    // 业务服务：把“动词”集中，实现流程与规则
    class AttendanceService
    {
        private List<Student> students = new List<Student>();
        private List<Course> courses = new List<Course>();
        private List<ClassSession> sessions = new List<ClassSession>();

        public Student AddStudent(string name)
        {
            var s = new Student(name);
            students.Add(s);
            return s;
        }

        public Course CreateCourse(string title)
        {
            var c = new Course(title);
            courses.Add(c);
            return c;
        }

        public void EnrollStudent(Guid courseId, Guid studentId)
        {
            var c = courses.FirstOrDefault(x => x.Id == courseId);
            var s = students.FirstOrDefault(x => x.Id == studentId);
            if (c == null || s == null) return;
            if (!c.EnrolledStudents.Any(x => x.Id == s.Id))
                c.EnrolledStudents.Add(s);
        }

        public ClassSession StartSession(Guid courseId)
        {
            var c = courses.FirstOrDefault(x => x.Id == courseId);
            if (c == null) return null;
            var sess = new ClassSession(c);
            sessions.Add(sess);
            return sess;
        }

        public void CheckIn(Guid sessionId, Guid studentId)
        {
            var sess = sessions.FirstOrDefault(x => x.Id == sessionId);
            if (sess == null) return;

            // 简单规则：仅允许已报名学生签到
            if (!sess.Course.EnrolledStudents.Any(s => s.Id == studentId))
            {
                Console.WriteLine($"[{DateTime.Now:T}] 学生 {studentId} 未报名课程 '{sess.Course.Title}'，签到被忽略。");
                return;
            }

            // 防止重复签到
            if (sess.Records.Any(r => r.StudentId == studentId))
            {
                Console.WriteLine($"[{DateTime.Now:T}] 学生已签到（忽略重复签到）。");
                return;
            }

            sess.Records.Add(new AttendanceRecord(studentId));
            var studentName = sess.Course.EnrolledStudents.First(s => s.Id == studentId).Name;
            Console.WriteLine($"[{DateTime.Now:T}] 签到：{studentName}");
        }

        public void PrintSessionReport(Guid sessionId)
        {
            var sess = sessions.FirstOrDefault(x => x.Id == sessionId);
            if (sess == null)
            {
                Console.WriteLine("未找到该课堂。");
                return;
            }

            Console.WriteLine("\n--- 出勤报告 ---");
            Console.WriteLine($"课程：{sess.Course.Title}");
            Console.WriteLine($"课堂开始时间：{sess.StartAt}");
            Console.WriteLine($"总报名人数：{sess.Course.EnrolledStudents.Count}");
            Console.WriteLine($"已签到人数：{sess.Records.Count}");

            foreach (var r in sess.Records)
            {
                var s = sess.Course.EnrolledStudents.FirstOrDefault(x => x.Id == r.StudentId);
                var name = s != null ? s.Name : $"未知({r.StudentId})";
                Console.WriteLine($"  - 出席：{name}（{r.CheckInTime:T}）");
            }

            var presentIds = new HashSet<Guid>(sess.Records.Select(r => r.StudentId));
            var absent = sess.Course.EnrolledStudents.Where(s => !presentIds.Contains(s.Id)).ToList();
            Console.WriteLine($"缺席人数：{absent.Count}");
            foreach (var a in absent)
                Console.WriteLine($"  - 缺席：{a.Name}");

            Console.WriteLine("-----------------\n");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var service = new AttendanceService();

            // 创建学生
            var alice = service.AddStudent("Alice");
            var bob = service.AddStudent("Bob");
            var carol = service.AddStudent("Carol");

            // 创建课程并报名
            var course = service.CreateCourse("C# 基础入门");
            service.EnrollStudent(course.Id, alice.Id);
            service.EnrollStudent(course.Id, bob.Id);
            service.EnrollStudent(course.Id, carol.Id);

            // 开始课堂
            var session = service.StartSession(course.Id);
            Console.WriteLine($"课程 '{course.Title}' 的课堂已开始（SessionId={session.Id}）。");

            // 模拟签到（Alice 和 Carol 签到）
            service.CheckIn(session.Id, alice.Id);
            System.Threading.Thread.Sleep(300);
            service.CheckIn(session.Id, carol.Id);

            // 打印报告
            service.PrintSessionReport(session.Id);

            Console.WriteLine("示例结束，按任意键退出。");
            Console.ReadKey();
        }
    }
}